<?php

namespace app\common\model\marketing;

use addons\xyb\XypHelper;

use app\common\model\marketing\label\Level;
use app\common\model\publics\Huati;
use think\Model;


class AssociationJobs extends Model
{

    // 表名
    protected $name = 'association_jobs';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    public static $grant_status_list = [
        1 => '进行中',
        2 => '已结束',
        3 => '已下架'
    ];
    public static $activity_method_list = [
        1 => '结束后发放',
        2 => '按天发放',
    ];

    public static $reward_method_list = [
        1 => '积分',
        2 => '青年币',
        3 => '优惠劵',
        4 => '积分+优惠劵',
        5 => '青年币+优惠劵',
    ];

    public static $push_method_list = [
        'image' => '图片加文本',
        'video' => '视频加文本',
        'text' => '纯文本',
    ];

    protected $append = [
        'association_info',
        'status_text',
        'grant_status_text',
        'activity_method_text',
        'job_date_text',
        'create_date',
        'label_level_name',
        'talk_name_text',
    ];
    public function getTalkNameTextAttr($value, $data){
        if(isset($data['talk_id']) && $data['talk_id']){
            return Huati::where('id', $data['talk_id'])->value('title');
        } else {
            return '';
        }
    }



    public function getAssociationInfoAttr($value, $data){
        if(isset($data['association_id']) && $data['association_id']){
            return Association::where('id', $data['association_id'])->value('name');
        } else {
            return '';
        }
        //return Association::where('id', $data['association_id'])->value('name');
    }

    public function getGrantStatusTextAttr($value, $data){
        if(isset($data['grant_status']) && $data['grant_status']) {
            $value = $value ? $value : (isset($data['grant_status']) ? $data['grant_status'] : '');
            return isset(self::$grant_status_list[$value]) ? self::$grant_status_list[$value] : '';
        }else{
            return '';
        }
    }

    public function getStatusTextAttr($value, $data){
        if(isset($data['grant_status']) && $data['grant_status']) {
            $value = $value ? $value : (isset($data['grant_status']) ? $data['grant_status'] : '');
            return isset(self::$grant_status_list[$value]) ? self::$grant_status_list[$value] : '';
        }else {
            return '';
        }
    }
    public function getActivityMethodTextAttr($value, $data){
        if(isset($data['activity_method']) && $data['activity_method']) {
            $value = $value ? $value : (isset($data['activity_method']) ? $data['activity_method'] : '');
            return isset(self::$activity_method_list[$value]) ? self::$activity_method_list[$value] : '';
        }else {
            return '';
        }
    }
    public function getJobDateTextAttr($value, $data){
        if(isset($data['start_time']) && $data['start_time'] && strlen( $data['start_time']) <= 11) {
            return date('Y-m-d', $data['start_time']) . ' ~ ' . date('Y-m-d', $data['end_time']);
        }else{
            return '';
        }
    }

    public function getLabelLevelNameAttr($value, $data){
        if(isset($data['label_level']) && $data['label_level']) {
            return Level::where('id', $data['label_level'])->value('name');
        }else{
            return '';
        }
    }
    public function getCreateDateAttr($value, $data){
        if(isset($data['createtime']) && $data['createtime']) {
            return date('Y-m-d H:i', $data['createtime']);
        }else{
            return '';
        }
    }
    public static function getMissionAdminLists()
    {
        $association_id = request()->param('association_id/a');
        $keyword = request()->param('keyword', '');
        $talk_id = request()->param('talk_id/a', '');
        $deadline = request()->param('deadline/a');
        $top_page = request()->param('top_page');
        $reward_method = request()->param('reward_method/a');
        $push_method = request()->param('push_method/a');
        $grant_status = request()->param('grant_status/a');
        $field = 'id,name,talk_id,start_time,end_time,top_page,push_method,weigh,reward_method,createtime,grant_status,
        grant_total,involved_total,association_id,reward_point,youth_point,reward_coupons_id,participation_rules';
        $query = self::field($field)->where('activity_method', 2);
        if ($association_id = XypHelper::stringToArray($association_id)) {
            $query->whereIn('association_id', $association_id);
        }
        if ($talk_id = XypHelper::stringToArray($talk_id)) {
            $query->whereIn('talk_id', $talk_id);
        }
        if ($keyword) {
            $query->where(function ($query) use ($keyword) {
                $query->where('id', 'like', "%{$keyword}%")
                    ->whereOr('name', 'like', "%{$keyword}%");
            });
        }
        if ($deadline_arr = XypHelper::stringToArray($deadline)) {
            $query->where('start_time','>',  XypHelper::getTimestamp($deadline_arr[0]))
                ->where('end_time','<',  XypHelper::getTimestamp($deadline_arr[1]));
        }
        if ($top_page) {
            $query->whereIn('top_page', $top_page - 1);
        }
        if ($reward_method = XypHelper::stringToArray($reward_method)) {
            $query->whereIn('reward_method', $reward_method);
        }
        if ($push_method = XypHelper::stringToArray($push_method)) {
            $query->whereIn('push_method', $push_method);
        }
        if ($grant_status = XypHelper::stringToArray($grant_status)) {
            $query->whereIn('grant_status', $grant_status);
        }
        return $query->order('id desc')->paginate(10);
    }
    public static function getAdminLists()
    {
        $association_id = request()->param('association_id/a');
        $keyword = request()->param('keyword', '');
        $deadline = request()->param('deadline/a');
        $grant_status = request()->param('grant_status/a');
        $field = '';
        $query = self::field($field);
        if ($association_id = XypHelper::stringToArray($association_id)) {
            $query->whereIn('association_id', $association_id);
        }
        if ($keyword) {
            $query->where(function ($query) use ($keyword) {
                $query->where('id', 'like', "%{$keyword}%")
                    ->whereOr('name', 'like', "%{$keyword}%");
            });
        }
        if ($deadline_arr = XypHelper::stringToArray($deadline)) {
            $query->where('start_time','>',  XypHelper::getTimestamp($deadline_arr[0]))
                ->where('end_time','<',  XypHelper::getTimestamp($deadline_arr[1]));
        }
        if ($grant_status = XypHelper::stringToArray($grant_status)) {
            $query->whereIn('grant_status', $grant_status);
        }
        return $query->order('id desc')->paginate(10);
    }

    public static function getAssociationJobsItems($association_id, $user_id)
    {
        $field = '*';
        $jobs_lists = self::field($field);
        $jobs_lists = $jobs_lists->where('association_id', $association_id)->select();
        if(!$jobs_lists){
            return [];
        }
        $jobs_list_maps = [];
        foreach ($jobs_lists as $key => $val){
            $jobs_list_maps[$key] = [];
            $jobs_list_maps[$key]['id'] = $val['id'];
            $jobs_list_maps[$key]['name'] = $val['name'];
            $jobs_list_maps[$key]['start_date'] = date('m.d', $val['start_time']);
            $jobs_list_maps[$key]['end_date'] = date('m.d', $val['end_time']);
            $jobs_list_maps[$key]['status'] = $val['grant_status'];
            $jobs_list_maps[$key]['reward_point'] = intval($val['reward_point']);
            $jobs_list_maps[$key]['activity_method'] = intval($val['activity_method']);
            $jobs_list_maps[$key]['involved_days'] = intval($val['involved_days']);
            $jobs_list_maps[$key]['execute_days'] = intval($val['execute_days']);
            $jobs_list_maps[$key]['enroll_info'] = AssociationUsers::getUsersJobsEnrollStatus($user_id, $association_id, $val['id']);
            if(!isset($jobs_list_maps[$key]['enroll_info']['deadline_date']) || !$jobs_list_maps[$key]['enroll_info']['deadline_date']){
                $jobs_list_maps[$key]['enroll_info']['deadline_date'] = date('Y-m-d', $val['end_time']);
            }
            if(!isset($jobs_list_maps[$key]['enroll_info']['surplus_days']) || !$jobs_list_maps[$key]['enroll_info']['surplus_days']){
                $jobs_list_maps[$key]['enroll_info']['surplus_days'] =$val['execute_days'];
            }
            if ($val['activity_method'] == 2) {
                $jobs_list_maps[$key]['reward_point'] = (int)self::getEveryDayAssociationRewardPoint($val['participation_rules']);
            }
            $jobs_list_maps[$key]['rules'] = self::formatAssociationRulesItems($association_id, $val['id'], $val);
        }
        return $jobs_list_maps;
    }



    /**
     * 格式化参与规则
     *
     * 该方法用于计算参与规则中每天关联的所有奖励点总数
     * 它首先将参与规则的JSON字符串转换为数组，然后计算所有奖励点的总和
     *
     * @param int $association_id 用户ID
     * @param int $user_id 用户ID
     * @param array $jobs 参与规则的JSON字符串，包含每天的奖励点信息
     * @return array 如果转换失败，返回0；否则返回所有奖励点的总和
     */

    public static function formatAssociationRulesItems($association_id, $user_id, $jobs)
    {
        if (!$participation_rules = XypHelper::formatJsonStringToArray($jobs['participation_rules'])) {
            return [];
        }
        $participation_rules_map = [];
        $reward_point = isset($jobs['reward_point']) ? $jobs['reward_point'] : 0;
        $reward_coupons = MarketingCoupons::getAssociationCouponsArray($jobs['reward_coupons_id']);
        foreach ($participation_rules as $k => $v) {
            $talk_name = '';
            $total_limit = 0;
            $complete_limit = 0;
            if ($v['talk_id']) {
                $talk_name = Huati::where('id', $v['talk_id'])->value('title');
            }
            $__key = isset($v['__key']) ? $v['__key'] : '';
            $image = $video = $text = [
                'stated' => false, 'limit' => 0, 'num' => 0, 'text' => 0, 'talk_id' => 0,
                'talk_name' => '', 'complete_num' => 0, 'complete_stated' => false
            ];
            if(isset($v['reward_coupons_id']) && $v['reward_coupons_id']){
                $reward_coupons = MarketingCoupons::getAssociationCouponsArray($v['reward_coupons_id']);
            }
            if (((int)$v['image_stated']) == 1) {
                $image['stated'] = true;
                $image['limit'] = (int)$v['image_limit'];
                $image['num'] = (int)$v['image_num'];
                $image['text'] = (int)$v['image_length'];
                if ($image['talk_id'] = ((int)$v['image_talk_id'])) {
                    $image['talk_name'] = Huati::where('id', $v['image_talk_id'])->value('title');
                } else {
                    $image['talk_name'] = $talk_name;
                }
                $image['complete_num'] = AssociationProgress::getUsersAssociationProgressTotal($user_id, $association_id, $jobs['id'], $__key, 'image');
                $image['complete_stated'] = ($image['limit'] == $image['complete_num']);
                $complete_limit = $image['complete_num'];
                $total_limit = $image['limit'];
            }
            if (((int)$v['video_stated']) == 1) {
                $video['stated'] = true;
                $video['limit'] = (int)$v['video_limit'];
                $video['num'] = (int)$v['video_num'];
                $video['text'] = (int)$v['video_length'];
                if ($video['talk_id'] = ((int)$v['video_talk_id'])) {
                    $video['talk_name'] = Huati::where('id', $v['video_talk_id'])->value('title');
                }else {
                    $video['talk_name'] = $talk_name;
                }
                $__key = isset($v['__key']) ? $v['__key'] : '';
                $video['complete_num'] = AssociationProgress::getUsersAssociationProgressTotal($user_id, $association_id, $jobs['id'], $__key, 'video');
                $video['complete_stated'] = ($video['limit'] == $video['complete_num']);
                $complete_limit += $video['complete_num'];
                $total_limit += $video['limit'];
            }
            if (((int)$v['text_stated']) == 1) {
                $text['stated'] = true;
                $text['limit'] = (int)$v['text_limit'];
                $text['text'] = (int)$v['text_length'];
                if ($text['talk_id'] = ((int)$v['text_talk_id'])) {
                    $text['talk_name'] = Huati::where('id', $v['text_talk_id'])->value('title');
                }else {
                    $text['talk_name'] = $talk_name;
                }
                $__key = isset($v['__key']) ? $v['__key'] : '';
                $text['complete_num'] = AssociationProgress::getUsersAssociationProgressTotal($user_id, $association_id, $jobs['id'], 'text');
                $text['complete_stated'] = ($text['limit'] == $text['complete_num']);
                $complete_limit += $text['complete_num'];
                $total_limit += $text['limit'];
            }
            $participation_rules_map[$k]['activity_method'] = isset($jobs['activity_method'])?$jobs['activity_method']:2;
            $participation_rules_map[$k]['total_limit'] = $total_limit;
            $participation_rules_map[$k]['talk_id'] = intval($v['talk_id']);
            $participation_rules_map[$k]['talk_name'] = $talk_name;
            $participation_rules_map[$k]['reward_point'] = (int)(isset($v['reward_point'])?$v['reward_point']:$reward_point);
            $participation_rules_map[$k]['reward_coupons_id'] = $reward_coupons;
            $participation_rules_map[$k]['complete_limit'] = $complete_limit;
            $participation_rules_map[$k]['complete_stated'] = ($complete_limit == $total_limit);
            $participation_rules_map[$k]['image'] = $image;
            $participation_rules_map[$k]['video'] = $video;
            $participation_rules_map[$k]['text'] = $text;
            $participation_rules_map[$k]['name'] = $v['name'];
            $participation_rules_map[$k]['unique_id'] = base64_encode($jobs->id.'_'.$__key);
        }
        return $participation_rules_map;
    }

    /**
     * 计算每日关联奖励点
     *
     * 该方法用于计算参与规则中每天关联的所有奖励点总数
     * 它首先将参与规则的JSON字符串转换为数组，然后计算所有奖励点的总和
     *
     * @param string $participation_rules 参与规则的JSON字符串，包含每天的奖励点信息
     * @return int 如果转换失败，返回0；否则返回所有奖励点的总和
     */
    public static function getEveryDayAssociationRewardPoint($participation_rules)
    {
        // 将参与规则的JSON字符串转换为数组，以便处理
        if (!$participation_rules = XypHelper::formatJsonStringToArray($participation_rules)) {
            // 如果转换失败，返回0
            return 0;
        }
        // 计算并返回所有奖励点的总和
        return array_sum(array_column($participation_rules, 'reward_point'));
    }





    /*获取用户可参加的日常活动*/
    public static function getDaysAssociationJobsByAssociationIds($association_ids, $user_id,$page = 1, $limit = 10)
    {
        $field = 'id,examine_method,participation_rules,reward_method,reward_point,youth_point,reward_coupons_id,
        push_method,talk_id,association_id,name,__key';
        /*获取用户已参加的日常任务*/
        $complete_jobs_ids = AssociationProgress::retrieveDailyTasksIdsUserParticipatedToday( $association_ids, $user_id);

        $query = self::field($field)
            ->where('association_id', 'in', $association_ids)
        ->where('activity_method', 2);
        if($complete_jobs_ids){
            $query->where('id', 'not in', $complete_jobs_ids);
        }
        return $query->where('grant_status', 1)->where('status', 1)
            ->where(function ($query){
                $query->where('start_time', 0)->whereOr('start_time', '<', time());

            })->where(function ($query){
                $query->where('end_time', 0)->whereOr('end_time', '>', time());
            })
            ->order('weigh desc,id desc')->paginate( [], false, ['page' => $page, 'limit' => $limit]);
    }


    /*获取用户可参加的日常活动；推荐的 */
    public static function getDaysAssociationJobsRecommendByAssociationIds($association_ids, $user_id, $limit = 10)
    {

        /*获取用户已参加的日常任务*/
        $complete_jobs_ids = AssociationProgress::retrieveDailyTasksIdsUserParticipatedToday( $association_ids, $user_id);
        $field = 'id,examine_method,participation_rules,reward_method,reward_point,youth_point,reward_coupons_id,
        push_method,talk_id,association_id,name,__key';
        $query = self::field($field)
            ->where('association_id', 'in', $association_ids)
            ->where('activity_method', 2)
            ->where('top_page', 1);
        if($complete_jobs_ids){
            $query->where('id', 'not in', $complete_jobs_ids);
        }
        $recommend_lists = $query->where('grant_status', 1)->where('status', 1)
            ->where(function ($query){
                $query->where('start_time', 0)->whereOr('start_time', '<', time());

            })->where(function ($query){
                $query->where('end_time', 0)->whereOr('end_time', '>', time());
            })
            ->order('weigh desc,id desc')->select();
        $job_lists = [];
        if(!$recommend_lists || count($recommend_lists) < $limit){
            $query = self::field($field)
                ->where('association_id', 'in', $association_ids)
                ->where('activity_method', 2)
                ->where('top_page', 0);
            if($complete_jobs_ids){
                $query->where('id', 'not in', $complete_jobs_ids);
            }
            $job_lists = $query->where('grant_status', 1)->where('status', 1)
                ->where(function ($query){
                    $query->where('start_time', 0)->whereOr('start_time', '<', time());

                })->where(function ($query){
                    $query->where('end_time', 0)->whereOr('end_time', '>', time());
                })
                ->order('weigh desc,id desc')->limit(($limit - count($recommend_lists)))->select();
        }
        return array_values(array_filter(array_merge($recommend_lists, $job_lists)));

    }

    public static function formatDailyAssociationRulesItems($jobs)
    {

        if (!$push_rules = XypHelper::formatJsonStringToArray($jobs['participation_rules'])) {
            return [];
        }
        $response = [];
        $reward_coupons = [];
        if((isset($jobs['reward_coupons_id']) ? $jobs['reward_coupons_id'] : 0)){
            $reward_coupons = MarketingCoupons::getAssociationCouponsArray($jobs['reward_coupons_id']);
        }
        $push_method = isset($jobs['push_method'])?$jobs['push_method']:'image';
        $response['activity_method'] = isset($jobs['activity_method'])?(int)$jobs['activity_method']:2;
        $response['reward_method'] = isset($jobs['reward_method'])?(int)$jobs['reward_method']:1;
        $response['push_method'] = $push_method;
        $response['total_limit'] = 1;
        $response['talk_id'] = intval($jobs['talk_id']);
        $response['talk_name'] =  $jobs['talk_name_text'];
        $response['reward_point'] =isset($jobs['reward_point']) ? (int)$jobs['reward_point'] : 0;
        $response['youth_point'] = isset($jobs['youth_point']) ? (int)$jobs['youth_point'] : 0;
        $response['reward_coupons_id'] = $reward_coupons;
        $response['complete_limit'] = 1;
        $response['complete_stated'] = false;
        $response['image'] = $push_method == 'image'? (isset($push_rules['image_num'])? (int)$push_rules['image_num'] : 0) : 0;
        $response['video'] = $push_method == 'video'? (isset($push_rules['video_num'])? (int)$push_rules['video_num'] : 0) : 0;
        $response['text'] = (isset($push_rules['text_num'])? (int)$push_rules['text_num'] : 0);
        $response['name'] = $jobs['name'];
        $response['unique_id'] = base64_encode($jobs['id'].'_'.($response['activity_method']).'_'.$jobs['__key']);

        return $response;
    }


    public static function getAssociationJobsDetailsItems($association_id)
    {
        $field = 'id,name,talk_id,start_time,end_time,top_page,grant_total,reward_method,reward_point,youth_point,
        reward_coupons_id,push_method,participation_rules,__key,weigh';
        $jobs_lists = self::field($field)->where('association_id', $association_id)->select();
        if(!$jobs_lists){
            return [];
        }

        foreach ($jobs_lists as $key => $val){
            $participation_rules = XypHelper::formatJsonStringToArray($val['participation_rules']);
            $jobs_lists[$key]['talk_id'] = intval($val['talk_id']);
            $jobs_lists[$key]['start_time'] = $val['start_time'] ? date('Y-m-d H:i:s', $val['start_time']) : '';
            $jobs_lists[$key]['end_time'] = $val['end_time'] ? date('Y-m-d H:i:s', $val['end_time']) : '';
            $jobs_lists[$key]['top_page'] = intval($val['top_page']);
            $jobs_lists[$key]['grant_total'] = intval($val['grant_total']);
            $jobs_lists[$key]['reward_method'] = intval($val['reward_method']);
            $jobs_lists[$key]['reward_point'] = intval($val['reward_point']);
            $jobs_lists[$key]['youth_point'] = intval($val['youth_point']);
            $jobs_lists[$key]['push_method'] = ($val['push_method']);
            $jobs_lists[$key]['reward_coupons_id'] = XypHelper::formatJsonStringToArray($val['reward_coupons_id']);
            $jobs_lists[$key]['image_num'] = isset($participation_rules['image_num'])? (int)$participation_rules['image_num'] : 0;
            $jobs_lists[$key]['video_num'] = isset($participation_rules['video_num'])? (int)$participation_rules['video_num'] : 0;
            $jobs_lists[$key]['text_num'] = isset($participation_rules['text_num'])? (int)$participation_rules['text_num'] : 0;
        }
        return $jobs_lists;
    }

}